import win32com.client
import logging

# 配置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

class Canoelibrary:
    """A custom library for interacting with CANoe using COM interface.
    This library can be imported into Robot Framework projects.
    """

    def __init__(self):
        """Initialize the CANoe application."""
        logging.info("初始化 CANoe 库。")
        self.canoe_app = None
        self.measurement = None
        self.configuration = None
        self.environment = None

    def start_canoe(self):
        """Start the CANoe application."""
        logging.info("正在启动 CANoe 应用程序...")
        try:
            self.canoe_app = win32com.client.Dispatch("CANoe.Application")
            self.canoe_app.Visible = True
            logging.info("CANoe 应用程序启动成功。")
        except Exception as e:
            logging.error(f"启动 CANoe 应用程序失败: {e}")
            raise Exception(f"Failed to start CANoe application: {e}")

    def load_configuration(self, config_path):
        """Load a CANoe configuration file (.cfg).

        Args:
            config_path (str): Path to the CANoe configuration file.
        """
        logging.info(f"正在加载配置文件: {config_path}...")
        if not self.canoe_app:
            logging.error("CANoe 应用程序未启动，请先启动。")
            raise Exception("CANoe application is not started. Please start it first.")

        try:
            self.configuration = self.canoe_app.Configuration
            self.configuration.Measurement.Load(config_path)
            logging.info(f"配置文件加载成功: {config_path}")
        except Exception as e:
            logging.error(f"加载配置文件失败: {e}")
            raise Exception(f"Failed to load configuration: {e}")

    def start_measurement(self):
        """Start the measurement in CANoe."""
        logging.info("正在启动测量...")
        if not self.configuration:
            logging.error("未加载配置文件，请先加载配置。")
            raise Exception("No configuration loaded. Please load a configuration first.")

        try:
            self.measurement = self.configuration.Measurement
            self.measurement.Start()
            logging.info("测量启动成功。")
        except Exception as e:
            logging.error(f"启动测量失败: {e}")
            raise Exception(f"Failed to start measurement: {e}")

    def stop_measurement(self):
        """Stop the measurement in CANoe."""
        logging.info("正在停止测量...")
        if not self.measurement:
            logging.error("测量未运行。")
            raise Exception("Measurement is not running.")

        try:
            self.measurement.Stop()
            logging.info("测量停止成功。")
        except Exception as e:
            logging.error(f"停止测量失败: {e}")
            raise Exception(f"Failed to stop measurement: {e}")

    def close_canoe(self):
        """Close the CANoe application."""
        logging.info("正在关闭 CANoe 应用程序...")
        if self.canoe_app:
            try:
                self.canoe_app.Quit()
                logging.info("CANoe 应用程序关闭成功。")
            except Exception as e:
                logging.error(f"关闭 CANoe 应用程序失败: {e}")
                raise Exception(f"Failed to close CANoe application: {e}")

    def get_signal_value(self, signal_name):
        """
        获取指定信号的值
        :param signal_name: 信号名称
        :return: 信号值
        """
        logging.info(f"正在获取信号值: {signal_name}...")
        if not self.measurement:
            logging.error("测量未运行，无法获取信号值。")
            raise Exception("CANoe 测量未运行，无法获取信号值")

        try:
            signal = self.canoe_app.CANalyzer.CAPL.CAN.Message[signal_name]
            if signal is None:
                logging.error(f"信号未找到: {signal_name}")
                raise Exception(f"信号 {signal_name} 未找到")
            logging.info(f"获取信号值成功: {signal_name} = {signal.Value}")
            return signal.Value
        except Exception as e:
            logging.error(f"获取信号值失败: {e}")
            raise Exception(f"Failed to get signal value: {e}")

    def initialize_canoe(self, canoe_config_file_path):
        """
        初始化 CANoe，加载配置文件并启动测量
        :param canoe_config_file_path: CANoe 配置文件路径
        """
        logging.info(f"正在初始化 CANoe，配置文件路径: {canoe_config_file_path}...")
        try:
            # 启动 CANoe 应用程序
            self.canoe_app = win32com.client.Dispatch("CANoe.Application")
            self.canoe_app.Visible = True  # 如果需要在前台运行 CANoe，设置为 True

            # 加载配置文件
            self.configuration = self.canoe_app.Configuration
            self.configuration.Measurement.Load(canoe_config_file_path)

            # 获取测量对象
            self.measurement = self.canoe_app.Measurement

            # 启动测量
            self.measurement.Start()

            # 获取环境变量对象（用于后续操作，如设置环境变量等）
            self.environment = self.canoe_app.Environment

            logging.info(f"CANoe 初始化完成，配置文件路径：{canoe_config_file_path}")
        except Exception as e:
            logging.error(f"初始化 CANoe 失败: {e}")
            raise Exception(f"Failed to initialize CANoe: {e}")